package model

import (
	"time"

	"bmember/pkg/util"
)

const (
	IntegralConsum         int8 = 1  // 消费积分
	IntegralConsumRefund   int8 = 2  // 消费积分退回
	IntegralExchange       int8 = 3  // 积分兑换
	IntegralExchangeRefund int8 = 4  // 积分兑换退回
	IntegralAward          int8 = 5  // 奖励积分
	IntegralAwardCancel    int8 = 6  // 奖励积分退回
	IntegralSignIn         int8 = 7  // 签到积分
	IntegralCleanUp        int8 = 99 // 积分清零

	IntegralConsumStr         = "consumption"        // 消费积分
	IntegralConsumRefundStr   = "consumption_refund" // 消费积分退回
	IntegralExchangeStr       = "exchange"           // 积分兑换
	IntegralExchangeRefundStr = "exchange_refund"    // 积分兑换退回
	IntegralAwardStr          = "award"              // 奖励积分
	IntegralAwardCancelStr    = "award_cancel"       // 奖励积分退回
	IntegralSignInStr         = "sign"               // 签到积分
	IntegralCleanUpStr        = "clean_up"           // 积分清零
)

// IntegralRemark 积分备注
type IntegralRemark struct {
	Reason string `json:"reason"`
}

// IntegralLog 积分日志
type IntegralLog struct {
	Id            int64     `json:"id" sql:"id"`
	BrandId       int64     `json:"brand_id" sql:"brand_id"`               // 品牌id
	StoreId       int64     `json:"store_id" sql:"store_id"`               // 门店id， 0~品牌
	GroupId       int64     `json:"group_id" sql:"group_id"`               // 体系id
	CardId        int64     `json:"card_id" sql:"card_id"`                 // 卡id
	MemberId      int64     `json:"member_id" sql:"member_id"`             // 会员id
	AccId         int64     `json:"acc_id" sql:"acc_id"`                   // 账户id
	IntType       int8      `json:"int_type" sql:"int_type"`               // 积分类型
	Num           int64     `json:"num" sql:"num"`                         // 积分数
	PayOrderNo    string    `json:"pay_order_no" sql:"pay_order_no"`       // 支付订单号
	RefundOrderNo string    `json:"refund_order_no" sql:"refund_order_no"` // 退款单号
	EmpId         int64     `json:"emp_id" sql:"emp_id"`                   // 操作员工id
	Amount        int64     `json:"amount" sql:"amount"`                   // 涉及金额
	Remark        []byte    `json:"remark" sql:"remark"`                   // 备注
	CreatedAt     time.Time `json:"created_at" sql:"created_at"`
	UpdatedAt     time.Time `json:"updated_at" sql:"updated_at"`
	DeletedAt     int64     `json:"deleted_at" sql:"deleted_at"`
}

// NewIntegralLog 新建积分记录
func NewIntegralLog(brandId, storeId, groupId, cardId, memberId, accId int64, empId int64) *IntegralLog {
	now := util.GetNow()
	return &IntegralLog{
		BrandId:   brandId,
		StoreId:   storeId,
		GroupId:   groupId,
		CardId:    cardId,
		MemberId:  memberId,
		AccId:     accId,
		EmpId:     empId,
		Remark:    []byte("{}"),
		CreatedAt: now,
		UpdatedAt: now,
	}
}

// SetNum 设置积分数
func (i *IntegralLog) SetNum(balType int8, cnt uint64) error {
	switch balType {
	case IntegralConsumRefund, IntegralExchange, IntegralAwardCancel, IntegralCleanUp:
		i.Num = -int64(cnt)
		i.IntType = balType
	case IntegralConsum, IntegralExchangeRefund, IntegralAward, IntegralSignIn:
		i.Num = int64(cnt)
		i.IntType = balType
	default:
		return InvalidEnum
	}
	i.UpdatedAt = util.GetNow()
	return nil
}

// Consumption 消费
func (i *IntegralLog) Consumption(num, amount uint64, payOrderNo string) {
	_ = i.SetNum(IntegralConsum, num)
	i.Amount = int64(amount)
	i.PayOrderNo = payOrderNo
}

// ConsumptionRefund 消费退款
func (i *IntegralLog) ConsumptionRefund(num, amount uint64, payOrderNo, refundOrderNo string) {
	_ = i.SetNum(IntegralConsumRefund, num)
	i.Amount = -int64(amount)
	i.PayOrderNo = payOrderNo
	i.RefundOrderNo = refundOrderNo
}

// Exchange 积分兑换
func (i *IntegralLog) Exchange(num uint64) {
	_ = i.SetNum(IntegralExchange, num)
}

// ExchangeRefund 兑换退
func (i *IntegralLog) ExchangeRefund(num uint64) {
	_ = i.SetNum(IntegralExchangeRefund, num)
}

// Award 奖励
func (i *IntegralLog) Award(num uint64) {
	_ = i.SetNum(IntegralAward, num)
}

// CancelAward 奖励退
func (i *IntegralLog) CancelAward(num uint64) {
	_ = i.SetNum(IntegralAwardCancel, num)
}

// GetRemark 获取备注
func (i *IntegralLog) GetRemark() *IntegralRemark {
	ret := &IntegralRemark{}
	if i.Remark != nil {
		_ = json.Unmarshal(i.Remark, ret)
	}
	return ret
}

// SetRemark 设置备注
func (i *IntegralLog) SetRemark(r *IntegralRemark) {
	if r != nil {
		i.Remark, _ = json.Marshal(r)
		i.UpdatedAt = util.GetNow()
	}
}

// SetReason 设置原因
func (i *IntegralLog) SetReason(r string) {
	if r != "" {
		remark := i.GetRemark()
		remark.Reason = r
		i.SetRemark(remark)
	}
}

// GetIntegralType 积分类型 string
func (i *IntegralLog) GetIntegralType() string {
	switch i.IntType {
	case IntegralConsum:
		return IntegralConsumStr
	case IntegralConsumRefund:
		return IntegralConsumRefundStr
	case IntegralExchange:
		return IntegralExchangeStr
	case IntegralExchangeRefund:
		return IntegralExchangeRefundStr
	case IntegralAward:
		return IntegralAwardStr
	case IntegralAwardCancel:
		return IntegralAwardCancelStr
	case IntegralSignIn:
		return IntegralSignInStr
	case IntegralCleanUp:
		return IntegralCleanUpStr
	default:
		return ""
	}
}
